
// ---------------------------
// UI基类：UIBase
// ---------------------------

import { _decorator, Button, Component, EventHandler, tween, Vec3, Node } from 'cc';
import { UIManager } from './UIManager';
const { ccclass, property } = _decorator;


@ccclass('UIBase')
export abstract class UIBase extends Component {
    private _nodeCache: Map<string, Node> = new Map();
    private _componentCache: Map<string, Component> = new Map();

    // 缓存策略枚举
    static CacheStrategy = {
        PRECACHE_ALL: 0,     // 预缓存所有节点
        PRECACHE_PATHS: 1,   // 预缓存指定路径
        ON_DEMAND: 2         // 按需缓存
    }

    // 缓存策略配置
    private _cacheStrategy: number = UIBase.CacheStrategy.ON_DEMAND;
    private _precachedPaths: Set<string> = new Set();

    // -------------------------------------------------------
    // 缓存配置方法
    // -------------------------------------------------------

    /**
     * 设置缓存策略
     * @param strategy 缓存策略
     * @param paths 需要预缓存的路径列表
     */
    protected setCacheStrategy(strategy: number, paths: string[] = []): void {
        this._cacheStrategy = strategy;
        this._precachedPaths = new Set(paths);

        switch (strategy) {
            case UIBase.CacheStrategy.PRECACHE_ALL:
                this._precacheAll();
                break;
            case UIBase.CacheStrategy.PRECACHE_PATHS:
                this._precachePaths();
                break;
        }
    }

    // 预缓存所有节点
    private _precacheAll(): void {
        this._traverseNodes(this.node, (fullPath, node) => {
            this._cacheNode(fullPath, node);
        });
    }

    // 预缓存指定路径
    private _precachePaths(): void {
        for (const path of this._precachedPaths) {
            const node = this._findNodeWithoutCache(path);
            if (node) {
                const fullPath = this._getNodePath(node);
                this._cacheNode(fullPath, node);
            }
        }
    }

    // -------------------------------------------------------
    // 智能查找方法
    // -------------------------------------------------------

    public find<T extends Component>(path: string, componentType?: { new(): T }): T | Node | Component | null {
        // 尝试从缓存获取
        const cached = this._getFromCache(path, componentType);
        if (cached) return cached;

        // 缓存未命中，执行查找
        const node = this._findNodeWithoutCache(path);
        if (!node) {
            throw new Error(`Node not found: ${path}`);
        }

        // 缓存节点
        if (this._cacheStrategy !== UIBase.CacheStrategy.ON_DEMAND) {
            const fullPath = this._getNodePath(node);
            this._cacheNode(fullPath, node);
        }

        // 处理组件查找
        if (componentType) {
            const comp = node.getComponent(componentType);
            if (!comp) {
                throw new Error(`Component ${componentType.name} not found`);
            }
            return comp;
        }

        return node;
    }

    // 从缓存获取
    private _getFromCache(path: string, componentType?: any): Node | Component | null {
        // 优先尝试完整路径匹配
        if (this._nodeCache.has(path)) {
            const node = this._nodeCache.get(path)!;
            if (!componentType) return node;

            const compKey = `${path}_${componentType.name}`;
            if (this._componentCache.has(compKey)) {
                return this._componentCache.get(compKey)!;
            }
        }

        return null;
    }

    // 无缓存查找
    private _findNodeWithoutCache(path: string): Node | null {
        let currentNode: Node = this.node;
        const segments = path.split('/');

        for (const segment of segments) {
            currentNode = this._findDirectChild(currentNode, segment);
            if (!currentNode) return null;
        }

        return currentNode;
    }

    // 高效查找直接子节点
    private _findDirectChild(parent: Node, name: string): Node | null {
        // 优化：直接访问children数组避免API调用
        for (const child of parent.children) {
            if (child.name === name) return child;
        }
        return null;
    }

    // -------------------------------------------------------
    // 缓存管理
    // -------------------------------------------------------

    // 缓存节点及其组件
    private _cacheNode(fullPath: string, node: Node): void {
        this._nodeCache.set(fullPath, node);

        // 自动缓存所有组件
        const components = node.getComponents(Component);
        for (const comp of components) {
            const compKey = `${fullPath}_${comp.constructor.name}`;
            this._componentCache.set(compKey, comp);
        }
    }

    // 获取节点完整路径
    private _getNodePath(node: Node): string {
        const path: string[] = [];
        let current: Node | null = node;

        while (current && current !== this.node) {
            path.unshift(current.name);
            current = current.parent;
        }

        return path.join('/');
    }

    // 遍历所有节点（用于预缓存）
    private _traverseNodes(root: Node, callback: (path: string, node: Node) => void): void {
        const queue: Node[] = [root];

        while (queue.length > 0) {
            const node = queue.shift()!;
            const fullPath = this._getNodePath(node);

            callback(fullPath, node);

            // 添加子节点
            for (let i = 0; i < node.children.length; i++) {
                queue.push(node.children[i]);
            }
        }
    }

    // 清理缓存
    protected clearCache(): void {
        this._nodeCache.clear();
        this._componentCache.clear();
    }

    /**
     * 智能自动绑定节点
     * @param prefixes 节点名前缀列表（如["btn", "txt"]）
     * @param cache 是否缓存绑定的节点
     */
    protected autoBind(prefixes: string[] = ["btn", "txt", "img"], cache: boolean = true): void {
        const regex = new RegExp(`^(${prefixes.join('|')})[A-Z]\\w*$`);

        this._traverseNodes(this.node, (path, node) => {
            if (regex.test(node.name)) {
                const propName = this._getPropName(node.name);
                // (this as any)[propName] = node;
                // 确保不覆盖已有属性
                if (!(this as any)[propName]) {
                    (this as any)[propName] = node.getComponent(Component) || node;
                }

                if (cache) {
                    this._nodeCache.set(path, node);
                }
            }
        });
    }

    // 转换节点名为属性名
    private _getPropName(nodeName: string): string {
        // btnStart -> start
        // txtScore -> score
        // return nodeName.replace(/^[a-z]+/, '').replace(/^\w/, c => c.toLowerCase());


        // 处理 btnStart → startBtn 的转换
        const prefixMatch = nodeName.match(/^([a-z]+)([A-Z].*)$/);
        if (prefixMatch) {
            const [_, prefix, rest] = prefixMatch;
            return rest.charAt(0).toLowerCase() + rest.slice(1) + prefix.charAt(0).toUpperCase() + prefix.slice(1);
        }
        return nodeName;
    }


    /**
     * UI名称（可选，默认使用节点名）
     */
    public get uiName(): string {
        return this.node.name;
    }

    // UI初始化（资源加载后）
    public async onInit(data?: any): Promise<void> {
        // 可重写
    }

    // UI显示时
    public async onShow(data?: any): Promise<void> {
        // 可重写
    }

    // UI隐藏时
    public async onHide(): Promise<void> {
        // 可重写
    }

    // 播放显示动画
    public async playShowAnimation(): Promise<void> {
        // 默认实现（可重写）
        return new Promise(resolve => {
            // 简单动画示例
            this.node.scale = new Vec3(0, 0, 0);
            tween(this.node)
                .to(0.3, { scale: new Vec3(1, 1, 1) }, { easing: 'backOut' })
                .call(() => resolve())
                .start();
        });
    }

    // 播放隐藏动画
    public async playHideAnimation(): Promise<void> {
        // 默认实现（可重写）
        return new Promise(resolve => {
            tween(this.node)
                .to(0.2, { scale: new Vec3(0, 0, 0) })
                .call(() => resolve())
                .start();
        });
    }

    // UI关闭（供按钮调用）
    public closeUI(): void {
        UIManager.instance.hideUI(this.node.name);
    }

    // 添加事件监听（自动管理）
    protected addEventListeners(): void {
        // 可重写
    }

    // 移除事件监听（自动管理）
    protected removeEventListeners(): void {
        // 可重写
    }

    protected onEnable(): void {
        this.addEventListeners();
    }

    protected onDisable(): void {
        this.removeEventListeners();
    }

    /**
     * 安全添加按钮事件
     * @param button 按钮节点
     * @param handler 事件处理函数
     * @param customEventData 自定义数据
     */
    protected addButtonEvent(button: Button, handler: () => void, customEventData?: any): void {
        if (!button) return;

        const clickHandler = new EventHandler();
        clickHandler.target = this.node;
        clickHandler.component = 'UIBase';
        clickHandler.handler = 'onButtonClick';
        clickHandler.customEventData = customEventData;

        button.clickEvents.push(clickHandler);
        this._buttonHandlers.set(button, handler);
    }

    // 按钮事件映射
    private _buttonHandlers: Map<Button, () => void> = new Map();

    // 按钮点击统一处理
    private onButtonClick(button: Button, customEventData?: any): void {
        const handler = this._buttonHandlers.get(button);
        if (handler) {
            handler();
        }
    }



    protected onDestroy(): void {
        this.clearCache();
    }
}

